10004. Раскраска двумя цветами
Имеется связный неориентированный
граф. Определить, можно ли покрасить его вершины двумя цветами так, чтобы никакие
две соседние вершины не были покрашены одним цветом.
Вход. Состоит
из нескольких тестов. Первая строка каждого теста содержит количество вершин n (1 < n < 200) в графе. Вторая строка
содержит количество ребер l. Каждая из следующих l строк содержит два числа –
номера вершин графа, соединенные ребром. Вершины графа нумеруются числами от 0
до n – 1. Последняя строка содержит n = 0 и не обрабатывается.
Выход. Для каждого теста вывести строку
“BICOLORABLE.”, если вершины графа можно раскрасить требуемым
образом, и “NOT BICOLORABLE.” иначе.
3
3
0 1
1 2
2 0
9
8
0 1
0 2
0 3
0 4
0 5
0 6
0 7
0 8
0
Пример выхода
NOT BICOLORABLE.
BICOLORABLE.
поиск в глубину
Для решения задачи воспользуемся
поиском в глубину. Изначально вершины не просмотрены, пометим их все цветом 0.
По мере прохождения по вершинам будем красить их в два цвета: 1 и 2. Если
текущая вершина имеет цвет i (i = 1, 2), то следующую вершину, в которую мы попадаем при
поиске в глубину, красим в цвет 3 – i. При этом проверяем, чтобы две соседние вершины не были
покрашены в одинаковый цвет.
Матрицу смежности графа храним в
массиве g размера MAX = 200. Массив mark содержит информацию о цвете вершины.
Глобальная переменная Error отвечает
за правильность раскраски: как только найдутся две соседние вершины,
покрашенные одинаково, переменная примет значение 1.
#define MAX 200
int g[MAX][MAX], mark[MAX], Error;
Процедура dfs выполняет поиск в
глубину. Ей передаются два параметра: текущая вершина v и ее цвет color. Если
уже встретился случай невозможности требуемой раскраски (Error = 1), то выйти из процедуры.
Помечаем вершину v цветом color. Ищем непросмотренную вершину i, в которую можно пойти продолжив
поиск в глубину. При этом если соседняя вершина i уже была просмотрена, проверяем
условие окрашенности вершин v и i в разные цвета. Если указанные
вершины покрашены в одинаковый цвет, устанавливаем Error = 1.
void dfs(int v,int color)
{
int i;
if (Error) return;
mark[v] = color;
for(i = 0; i < n; i++)
if
(g[v][i])
if (!mark[i]) dfs(i,3-color); else
if (mark[v] == mark[i]) Error = 1;
}
Основной цикл программы. Читаем
число вершин графа n и количество
ребер l. Обнуляем матрицу смежности и
массив mark.
while(scanf("%d %d",&n,&l),
n)
{
memset(g,0,sizeof(g));
memset(mark,0,sizeof(mark));
Читаем данные графа.
for(i = 0; i < l; i++)
{
scanf("%d %d",&a,&b);
g[a][b] =
g[b][a] = 1;
}
Обнуляем значение переменной Error, запускаем процедуру поиска в
глубину с нулевой вершины.
Error = 0; dfs(0,1);
В зависимости от значения
переменной Error выводим результат.
if (Error) printf("NOT BICOLORABLE.\n");
else printf("BICOLORABLE.\n");
}